<?php

namespace App\Http\Controllers\order;

use App\Http\Controllers\Controller;
use App\Jobs\Recharge;
use App\Models\Admin\Supplier;
use App\Models\Admin\SupplierConfiguration;
use App\Models\Mysql\XnIp;
use App\Models\Mysql\XnMerchant;
use App\Models\Mysql\XnMerchantBill;
use App\Models\Mysql\XnMerchantGoodsInvoicing;
use App\Models\Mysql\XnOrder;
use App\Models\Mysql\XnOrderBill;
use App\Models\Mysql\XnSupplierGoods;
use App\Recharge\Library;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use PDO;
use Throwable;

class PlaceOrderController extends Controller
{
    /**
     * @param Request $request
     */
    public function __construct(public Request $request)
    {
    }

    //下单
    public function order(Request $request)
    {
        $params = $request->all();
        Log::channel('api_request')->info(request()->get('db', 'supplier') . json_encode($params));
        $ip = $request->getClientIp();
        if (!$request->filled('business_number')) {
            return $this->sendError('请传入商户号', '1001');
        }

//        if (!XnIp::where(['info' => $ip, 'merchant_number' => $params['business_number']])->first()) {
//            return $this->sendError('访问拒绝','1002');
//        }
        if (!$request->filled('product_id')) {
            return $this->sendError('请传入商品编码', '1001');
        }
        if (!$request->filled('account')) {
            return $this->sendError('请传入充值账号', '1001');
        }
        if (!$request->filled('number')) {
            return $this->sendError('请传入充值数量', '1001');
        }
        if (!$request->filled('order_sn')) {
            return $this->sendError('请传入外部订单号', '1001');
        }
        /** @var XnMerchant|null $merchant * */
        $merchant = XnMerchant::query()->where('merchant_number', $params['business_number'])->first();
        if (!$merchant) {
            return $this->sendError('商户不存在', '1001');
        }
        if (!$request->filled('sign')) {
            return $this->sendError('请传入签名', '1001');
        }
//        if (!$this->sign($merchant['secret_key'],$params)){
//            return $this->sendError('sign签名错误，排除空值，按照字典排序后json，在拼接密钥后md5数据得到sign','1005');
//        }
        if ($merchant->merchant_type == 0) {
            return $this->sendError('无下单商品权限，请联系供应商开通', '1004');
        }
        /** @var XnSupplierGoods|null $goods_info * */
        $goods_info = XnSupplierGoods::query()->where('id', $params['product_id'])->first();
        if (!$goods_info) {
            return $this->sendError('商品不存在,请确认编码是否正确', '1004');
        }
        // 检测是否是带票的 是带票的查带票价格
        if ($merchant->merchant_type == 2) {
            /** @var XnMerchantGoodsInvoicing|null $invoice * */
            $invoice = XnMerchantGoodsInvoicing::query()->where(['goods_id' => $params['product_id'], 'merchant_num' => $params['business_number']])->first();
            if (!$invoice) {
                return $this->sendError('商品未配置', '1004');
            }
            $goods_info->fill(['price' => $invoice->price, 'release' => $invoice->release]);
        }
        if ($goods_info->release != 1) {
            return $this->sendError('商品未上架', '1004');
        }
        if (empty($goods_info->price)) {
            return $this->sendError('商品价格异常，请联系商户', '1004');
        }
        if (XnOrder::query()->where(['merchant_order_num' => $params['order_sn'], 'merchant_number' => $params['business_number']])->first()) {
            return $this->sendError('订单号重复', '1003');
        }
        if (!$request->filled('callback_url')) {
            $params['callback_url'] = '';
        }
        if (!$request->filled('user_ip')) {
            $params['user_ip'] = $request->getClientIp();
        }
        if ($request->filled('price')) {
            if ($params['price'] < $goods_info->price) {
                return $this->sendError('商品价格高于进货价,进货价为' . $goods_info['price']. '您的价格为' . $params['price'], '1004');
            }
        }
        $money_all = round($params['number'] * $goods_info['price'], 4);
        $balance = round($merchant['balance'] - $merchant['deduction_balance'], 4);
        if ($balance < $money_all) {
            return $this->sendError('账户余额不足', '1006');
        }
        try {
            $params['url'] = $_SERVER['HTTP_SHABINGINX'];
            $params['db'] = request()->get('db', 'supplier');
            $params['goods_belong'] = $goods_info['goods_belong'];
            return $this->sendResponse($this->makeOrderInfo($merchant, $goods_info, $params), '订单提交成功','200');
        } catch (\Exception $e) {
            Log::channel('api_request')->info('error', error2array($e));
            return $this->sendError('系统错误', '9999');
        }
    }

    //批量下单
    public function batch_order(Request $request)
    {
        $params = $request->all();
        Log::channel('batch_request')->info(request()->get('db', 'supplier') . json_encode($params));

        if (!$request->filled('product_id')) {
            return $this->sendError('请传入商品编码');
        }
        if (!$request->filled('account')) {
            return $this->sendError('请传入充值账号');
        }
        if (!$request->filled('number')) {
            return $this->sendError('请传入充值数量');
        }
        /** @var XnMerchant $merchant * */
        $merchant = auth('merchant')->user();
        if (!$merchant) {
            return $this->sendError('商户不存在');
        }
//        var_dump(md5($params['password']));
        if (md5($params['password']) != $merchant['transaction_password']) {
            return $this->sendError('交易密码错误');
        }
        if ($merchant->merchant_type == 0) {
            return $this->sendError('无下单商品权限，请联系供应商开通', '1004');
        }
        /** @var XnSupplierGoods|null $goods_info * */
        $goods_info = XnSupplierGoods::query()->where('id', $params['product_id'])->first();
        if (!$goods_info) {
            return $this->sendError('商品不存在,请确认编码是否正确');
        }
        // 检测是否是带票的 是带票的查带票价格
        if ($merchant->merchant_type == 2) {
            /** @var XnMerchantGoodsInvoicing|null $invoice * */
            $invoice = XnMerchantGoodsInvoicing::query()->where(['goods_id' => $params['product_id'], 'merchant_num' => $merchant->merchant_number])->first();
            if (!$invoice) {
                return $this->sendError('商品未配置' );
            }
            $goods_info->fill(['price' => $invoice->price, 'release' => $invoice->release]);
        }
        if ($goods_info->release != 1) {
            return $this->sendError('商品未上架');
        }
        if (empty($goods_info->price)) {
            return $this->sendError('商品价格异常，请联系商户', );
        }
        if (!$request->filled('callback_url')) {
            $params['callback_url'] = '';
        }
        if (!$request->filled('order_sn')) {
            $params['order_sn'] = '';
        }
        if ($request->filled('price')) {
            if ($params['price'] < $goods_info['price']) {
                return $this->sendError('商品价格高于进货价,进货价为' . $goods_info['price'], '您的价格为' . $params['price'], '1004');
            }
        }
        $money_all = round($params['number'] * $goods_info['price'] * count(explode(',', $params['account'])), 4);
        $balance = round($merchant['balance'] - $merchant['deduction_balance'], 4);
        if ($balance < $money_all) {
            return $this->sendError('账户余额不足');
        }
        try {
            $params['url'] = $_SERVER['HTTP_SHABINGINX'];
            $params['db'] = request()->get('db', 'supplier');
            $params['goods_belong'] = $goods_info['goods_belong'];
            $params['user_ip'] = $request->getClientIp();

            return $this->sendResponse($this->makeOrderInfo($merchant, $goods_info, $params), '订单提交成功');
        } catch (Throwable $e) {
            Log::channel('batch_request')->info(request()->get('db', 'supplier') . $e->getMessage());
            return $this->sendError('系统错误:' . $e->getMessage(), '9999');
        }
    }

    //验证sign
    private function sign($key, $info)
    {
        $m_sign = $info['sign'];
        $info = array_filter($info, function ($item) {
            return !empty($item);
        });
        unset($info['sign']);
        ksort($info);
        $sign = md5(json_encode($info) . $key);
        if ($sign != $m_sign) {
            return false;
        }
        return true;
    }

    /**
     * @param XnMerchant $merchant
     * @param XnSupplierGoods $good
     * @param array $info
     * @return array
     * @throws Exception
     */
    private function makeOrderInfo(XnMerchant $merchant, XnSupplierGoods $good, array $info): array
    {
        $orderNos = [];
        /** @var Supplier $supplier **/
        $supplier = Supplier::query()->find($this->request->attributes->get('supplier')?->id);
        if (!$supplier) {
            throw new Exception("供应商不存在");
        }
        foreach (explode(',', $info['account']) as $account) {
            $order = [
                'gid'               => $good->id,
                'goods_code'        => $good->goods_code,
                'account'           => $account,
                'order_sn'          => Library::order_no(),
                'price'             => $good->price,
                'unitPrice'         => $good->unit_price,
                'goods_num'         => $info['number'] ?? 1,
                'all_money'         => round($good->price * $info['number']),
                'recharge_time'     => date('Y-m-d H:i:s'),
                'goods_belong'      => $good->goods_belong,
                'merchant_number'   => $merchant->merchant_number,
                'callback_url'      => $info['callback_url'],
                'brand_id'          => $good->brand_id,
                'order_type'        => $merchant->merchant_type,
                'mechant_name'      => $merchant->nickname,
                'goods_name'        => $good->goods_name,
                'ip'                => $this->request->ip(),
            ];
            $orderNos[] = $order['order_sn'];
            //商户
            $balance  = round($merchant->balance - $merchant->deduction_balance, 4);
            // 账单
            $order_bill = [
                'goods_explain'     => $good->goods_name . '商品',
                'bookkeeping_type'  => 1,
                'order_sn'          => $order['order_sn'],
                'account'           => $order['account'],
                'price'             => $good->price,
                'goods_num'         => $info['number'],
                'business_type'     => 1,
                'budget_money'      => $order['all_money'],
                'goods_belong'      => $good->goods_belong,
                'ctime'             => date('Y-m-d H:i:s'),
                'merchant_name'     => $merchant->nickname,
                'goods_id'          => $good->id,
                'brand_id'          => $good->brand_id,
                'merchant_number'   => $merchant->merchant_number,
                'order_type'        => $merchant->merchant_type,
                'mechant_balance'   => ($balance - $order['all_money']),
                'mechant_before_balance'    => $balance,
                'mechant_after_balance'     => ($balance - $order['all_money']),
                'balance_before_change'     => $supplier->balance,
                'balance_after_change'      => $supplier->balance + $order['all_money'],
            ];
            $merchant_bill = [
                'merchant_number'           => $merchant->merchant_number,
                'time'                      => date('Y-m-d H:i:s', time()),
                'status'                    => 2,
                'before_transaction_balance'=> $balance,
                'transaction_amount'        => $order['all_money'],
                'after_transaction_balance' => ($balance - $order['all_money']),
                'merchant_order'            => $order['order_sn'],
                'brand_id'                  => $good->brand_id,
            ];
            Recharge::dispatch($supplier, $order, $merchant_bill, $order_bill, $good, $info)->onQueue($info['url'] . 'order');
        }
        return $orderNos;
    }

}
